package dmitrygusev.ratings;

import static dmitrygusev.io.StringUtils.isNullOrEmpty;
import static java.net.URLEncoder.encode;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import dmitrygusev.nanoxml.lite.XMLElement;
import dmitrygusev.ratings.model.Movie;
import dmitrygusev.ratings.services.KinokopilkaSource;
import dmitrygusev.ratings.services.KinopoiskSource;
import dmitrygusev.ratings.services.RatingQueryService;
import dmitrygusev.ratings.services.RatingQueryService.SearchMode;
import dmitrygusev.ratings.services.renders.ResultsXhtmlRender;
import dmitrygusev.ratings.services.renders.ResultsXmlRender;
import dmitrygusev.ratings.templates.TemplateLoader;

@SuppressWarnings("serial")
public class RatingsServlet extends HttpServlet {

	private static final Logger logger = Logger.getLogger(RatingsServlet.class);
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		processSearch(resp, req.getParameter("q"), req.getParameter("format"), req.getParameter("search-mode"));
	}

	private void responseWithQueryForm(HttpServletResponse resp) throws Error,
			IOException {
		XMLElement indexXml = TemplateLoader.loadTemplate("index-template.htm", "UTF-8");
		XMLElement queryFormXml = TemplateLoader.loadTemplate("query-form-template.htm", "UTF-8");

		ResultsXhtmlRender.fixCssLinks(indexXml);

		resp.setContentType("text/html");
		resp.setCharacterEncoding("UTF-8");
		
		resp.getWriter().println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");

		XMLElement queryDiv = indexXml.findById("query-form");
		queryDiv.setContent(null);
		queryDiv.addChild(queryFormXml);

		resp.getWriter().println(indexXml.toString());
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String format = req.getParameter("_format");
		String query = req.getParameter("_q");
		String searchMode = req.getParameter("fulltext");
		
		resp.sendRedirect("/ratings?q=" 
				+ (isNullOrEmpty(query) ? "" : encode(query, "UTF-8"))
				+ (isNullOrEmpty(format) ? "" : "&format=" + encode(format, "UTF-8"))
				+ (isNullOrEmpty(searchMode) ? "" : "&search-mode=fulltext"));
	}

	private void processSearch(HttpServletResponse resp, String query, String outputFormat, String searchMode)
			throws Error, IOException {
		
		if (query == null || query.isEmpty()) {
			responseWithQueryForm(resp);
		} else {
			resp.setCharacterEncoding("UTF-8");

			String output = null;
			
			if (outputFormat == null) {
				outputFormat = "xhtml";
			}
			
			SearchMode mode = SearchMode.BY_TITLE;
			
			if (! isNullOrEmpty(searchMode) && searchMode.equals("fulltext")) {
				mode = SearchMode.FULLTEXT;
			}
			
			logger.info(
				String.format("Processing search for query=\"%1s\" and outputFormat=\"%2s\" in \"%3s\" search mode",
						query, outputFormat, mode));

			if (outputFormat.equals("xml")) {
				resp.setContentType("text/xml");
			} else {
				resp.setContentType("text/html");
				resp.getWriter().println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
			}
			
			List<Movie> results = new RatingQueryService().
				execute(mode, 
						query, 
						new KinokopilkaSource(), 
						new KinopoiskSource());
			
			if (outputFormat.equals("xml")) {
				output = new ResultsXmlRender().render(results).toString();
			} else {
				output = new ResultsXhtmlRender().render(results, query, mode).toString();
			}
			
			//	NOTE: Uncomment for xml response
//			resp.getWriter().write("<!DOCTYPE html [");
//			resp.getWriter().write("<!ENTITY nbsp \"&#160;\">");
//			resp.getWriter().write("]>");

			resp.getWriter().write(output);
		}
	}
}
